<?php

namespace app\model\admin;

use app\model\BaseModel;
use think\facade\Db;

/**
 * 管理员权限规则模型
 * 对应数据表：oa_admin_rule
 */
class AdminRule extends BaseModel
{
    /**
     * 数据表名
     * @var string
     */
    protected $name = 'admin_rule';

    /**
     * 主键名
     * @var string
     */
    protected $pk = 'id';

    /**
     * 字段类型转换
     * @var array
     */
    protected $type = [
        'id' => 'integer',
        'pid' => 'integer',
        'name' => 'string',
        'title' => 'string',
        'icon' => 'string',
        'condition' => 'string',
        'remark' => 'string',
        'ismenu' => 'integer',
        'menutype' => 'string',
        'extend' => 'string',
        'py' => 'string',
        'pinyin' => 'string',
        'createtime' => 'int',
        'updatetime' => 'int',
        'weigh' => 'integer',
        'status' => 'integer',
    ];

    /**
     * 可搜索字段
     * @var array
     */
    protected $searchField = ['name', 'title', 'remark'];

    /**
     * 关联父权限
     * @return \think\model\relation\BelongsTo
     */
    public function parent()
    {
        return $this->belongsTo('app\model\admin\AdminRule', 'pid', 'id');
    }

    /**
     * 关联子权限
     * @return \think\model\relation\HasMany
     */
    public function children()
    {
        return $this->hasMany('app\model\admin\AdminRule', 'pid', 'id');
    }

    /**
     * 获取权限规则树
     * @param array $params 查询参数
     * @return array
     */
    public function getRuleTree($params = [])
    {
        $where = [];
        
        if (isset($params['status']) && $params['status'] !== '') {
            $where[] = ['status', '=', $params['status']];
        }
        
        if (isset($params['ismenu']) && $params['ismenu'] !== '') {
            $where[] = ['ismenu', '=', $params['ismenu']];
        }

        $rules = $this->where($where)
            ->order('weigh', 'asc')
            ->order('id', 'asc')
            ->select()
            ->toArray();

        return $this->buildTree($rules);
    }

    /**
     * 构建权限树
     * @param array $rules 权限列表
     * @param int $parentId 父ID
     * @return array
     */
    protected function buildTree($rules, $parentId = 0)
    {
        $tree = [];
        
        foreach ($rules as $rule) {
            if ($rule['pid'] == $parentId) {
                $children = $this->buildTree($rules, $rule['id']);
                if ($children) {
                    $rule['children'] = $children;
                }
                $tree[] = $rule;
            }
        }
        
        return $tree;
    }

    /**
     * 获取菜单权限
     * @param int $ismenu 是否为菜单 1是 0否
     * @return array
     */
    public function getMenuRules($ismenu = 1)
    {
        return $this->where('ismenu', $ismenu)
            ->where('status', 1)
            ->order('weigh', 'asc')
            ->order('id', 'asc')
            ->select()
            ->toArray();
    }

    /**
     * 获取用户权限列表
     * @param int $userId 用户ID
     * @return array
     */
    public function getUserRules($userId)
    {
        // 获取用户角色
        $userModel = new \app\model\admin\User();
        $user = $userModel->find($userId);
        
        if (!$user) {
            return [];
        }

        $roleIds = explode(',', $user['role_ids']);
        
        // 获取角色对应的权限ID列表
        $roleRules = Db::name('admin_group')
            ->where('id', 'in', $roleIds)
            ->where('status', 1)
            ->column('rules');

        if (empty($roleRules)) {
            return [];
        }

        // 合并所有角色的权限ID
        $allRuleIds = [];
        foreach ($roleRules as $rulesString) {
            if (!empty($rulesString)) {
                $ruleIds = array_filter(explode(',', trim($rulesString, ',')));
                $allRuleIds = array_merge($allRuleIds, $ruleIds);
            }
        }

        $allRuleIds = array_unique($allRuleIds);

        if (empty($allRuleIds)) {
            return [];
        }

        return $this->where('id', 'in', $allRuleIds)
            ->where('status', 1)
            ->order('weigh', 'asc')
            ->order('id', 'asc')
            ->select()
            ->toArray();
    }

    /**
     * 检查权限名称是否存在
     * @param string $name 权限名称
     * @param int $excludeId 排除的ID
     * @return bool
     */
    public function checkNameExists($name, $excludeId = 0)
    {
        $where = [['name', '=', $name]];
        
        if ($excludeId > 0) {
            $where[] = ['id', '<>', $excludeId];
        }

        return $this->where($where)->count() > 0;
    }

    /**
     * 创建权限规则
     * @param array $data 权限数据
     * @return bool
     */
    public function createRule($data)
    {
        if (empty($data['pid'])) {
            $data['pid'] = 0;
        }
        
        if (empty($data['weigh'])) {
            $data['weigh'] = 0;
        }
        
        if (empty($data['status'])) {
            $data['status'] = 1;
        }

        $data['createtime'] = time();
        $data['updatetime'] = time();
        
        return $this->save($data);
    }

    /**
     * 更新权限规则
     * @param int $id 权限ID
     * @param array $data 更新数据
     * @return bool
     */
    public function updateRule($id, $data)
    {
        $data['updatetime'] = time();
        
        return $this->where('id', $id)->update($data);
    }

    /**
     * 删除权限规则
     * @param int|array $ids 权限ID
     * @return bool
     */
    public function deleteRule($ids)
    {
        if (is_array($ids)) {
            // 检查是否有子权限
            $childrenCount = $this->where('pid', 'in', $ids)->count();
            if ($childrenCount > 0) {
                return false;
            }
            
            return $this->where('id', 'in', $ids)->delete();
        } else {
            // 检查是否有子权限
            $childrenCount = $this->where('pid', $ids)->count();
            if ($childrenCount > 0) {
                return false;
            }
            
            return $this->where('id', $ids)->delete();
        }
    }

    /**
     * 获取权限选项
     * @param int $pid 父权限ID
     * @return array
     */
    public function getRuleOptions($pid = 0)
    {
        $rules = $this->where('status', 1)
            ->order('weigh', 'asc')
            ->order('id', 'asc')
            ->select()
            ->toArray();

        return $this->buildOptions($rules, $pid);
    }

    /**
     * 构建权限选项
     * @param array $rules 权限列表
     * @param int $pid 父ID
     * @param string $prefix 前缀
     * @return array
     */
    protected function buildOptions($rules, $pid = 0, $prefix = '')
    {
        $options = [];
        
        foreach ($rules as $rule) {
            if ($rule['pid'] == $pid) {
                $options[$rule['id']] = $prefix . $rule['title'];
                $children = $this->buildOptions($rules, $rule['id'], $prefix . '　');
                $options = $options + $children;
            }
        }
        
        return $options;
    }

    /**
     * 搜索器：按父ID搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchPidAttr($query, $value)
    {
        $query->where('pid', $value);
    }

    /**
     * 搜索器：按是否为菜单搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchIsmenuAttr($query, $value)
    {
        $query->where('ismenu', $value);
    }

    /**
     * 搜索器：按状态搜索
     * @param \think\db\Query $query
     * @param int $value
     */
    public function searchStatusAttr($query, $value)
    {
        $query->where('status', $value);
    }

    /**
     * 搜索器：按名称搜索
     * @param \think\db\Query $query
     * @param string $value
     */
    public function searchNameAttr($query, $value)
    {
        $query->where('name', 'like', '%' . $value . '%');
    }

    /**
     * 搜索器：按标题搜索
     * @param \think\db\Query $query
     * @param string $value
     */
    public function searchTitleAttr($query, $value)
    {
        $query->where('title', 'like', '%' . $value . '%');
    }
}